<!--
 * @Author: huangmorong@mrcdevlab.com
 * @Date: 2025-01-24 14:36:52
 * @LastEditors: huangmorong@mrcdevlab.com
 * @LastEditTime: 2025-03-06 13:41:51
 * @FilePath: \mrc-performance\src\components\mrc_ess_Table\index.vue
 * @Description: 
-->
<template>
    <div class="h-full flex flex-col">

        <v-data-table v-model="selected" :return-object="props.returnObject" :item-value="props.itemValue"
            :show-select="props.showSelect" hover disable-sort fixed-header :items-per-page="paginationOptions.pagesize"
            :headers="headers" :items="items" :loading="props.loading || loading" class="my-data-table scroll_table_y"
            :class="{
                ['table-' + tableName]: true
            }" :style="tableType == 2 ? '--v-table-row-height: 40px' : ''" :name="'table-' + tableName">

            <!-- 空占位 -->
            <template v-slot:no-data>
                <mrc_ess_NoContent></mrc_ess_NoContent>
            </template>

            <!-- 置顶的头部 -->
            <template v-slot:thead>
                <slot name="thead">
                    <thead v-if="props.showAddBtn && !loading" style="position: relative;z-index: 0;">
                        <tr>
                            <th colspan="999" class="!px-0 !h-[auto]"
                                style="background-color: rgba(0,0,0,0) !important;">
                                <div class="px-4 py-2 flex justify-end" @click="handleAdd()">
                                    <div class="cursor-pointer flex align-center justify-center w-[24px] h-[24px]"
                                        v-ripple>
                                        <svg-icon iconClass="add-btn-ouline" size="24"></svg-icon>
                                    </div>
                                </div>
                            </th>
                        </tr>
                    </thead>
                </slot>
            </template>

            <!-- 表头 -->
            <template v-slot:[field['headerSlotKey']]=item v-for="(field, index) in tableFields" :key="index">
                <slot :name="field['headerSlotKey']" v-bind="item">
                    <!-- 设置表头 设置按钮 -->
                    <div class="flex justify-end" v-if="props.showSettings && field['key'] == 'opt'">
                        <div class="cursor-pointer flex align-center justify-center w-[24px] h-[24px]" v-ripple
                            @click="handleShowSettings">
                            <svg-icon iconClass="settings" size="16"></svg-icon>
                        </div>
                    </div>
                    <!-- 带排序的表头 -->
                    <div class="text-text--primary text-[12px] leading-[16px] font-[500] flex align-center cursor-pointer" :class="{
                        'justify-center': field['align'] == 'center'
                    }"
                        v-else-if="field.sortable == true" @click="handleChangeSortBy(field.key)">
                        <div class="overflow-ellipsis overflow-x-hidden">{{ field['i18n'] ? $t(field['i18n']) : $t(field['title']) }}</div>
                        <div v-if="field.sortable == true && sortBy == field.key" class="pl-1">
                            <div class="cursor-pointer" v-ripple>
                                <v-icon icon="mdi-arrow-up" size="16" v-if="sortOrder == 'asc'"></v-icon>
                                <v-icon icon="mdi-arrow-down" size="16" v-if="sortOrder == 'desc'"></v-icon>
                            </div>
                        </div>
                    </div>
                    <!-- 其余表头 -->
                    <div class="text-text--primary text-[12px] leading-[16px] font-[500] overflow-ellipsis overflow-x-hidden"
                        v-else>
                        {{ field['i18n'] ? $t(field['i18n']) : $t(field['title']) }}
                    </div>
                </slot>
            </template>

            <!-- 内容 -->
            <template v-slot:[field['itemSlotKey']]=item v-for="(field, index) in tableFields" :key="index">
                <div class="overflow-ellipsis overflow-x-hidden table-td-content">
                    <slot :name="field['itemSlotKey']" v-bind="item">
                        <!-- 操作 -->
                        <div class="flex align-center justify-between" v-if="field.key == 'opt' || field.key == 'Opt'">
                            <!-- 查看 按钮 -->
                            <tableViewBtn v-if="props.opt.includes('view')" @children-click="handleView(item)">
                            </tableViewBtn>
                            <!-- 编辑 按钮 -->
                            <tableEditBtn v-if="props.opt.includes('edit')" @children-click="handleEdit(item)">
                            </tableEditBtn>
                            <!-- 删除 按钮 -->
                            <mrc_ess_PopConfirm content="Are you sure to delete?" :autoClose="false"
                                @confirm="handleDel(item, $event)"
                                v-if="props.opt.includes('delete') || props.opt.includes('del')">
                                <template v-slot:btn>
                                    <tableDelBtn></tableDelBtn>
                                </template>
                            </mrc_ess_PopConfirm>
                        </div>
                        <!-- 带数据拖拽排序按钮的值 -->
                        <div class="text-text--primary text-[14px] font-[500] leading-[18px] flex align-center"
                            v-else-if="field.dataDragSortBtn == true && props.dataDragSortable">
                            <!-- 数据排序按钮 -->
                            <div class="sort-btn pr-4 cursor-move">
                                <svg-icon iconClass="sort-btn" size="16"></svg-icon>
                            </div>
                            <!-- 值 -->
                            <div class="overflow-ellipsis overflow-x-hidden">
                                {{ item.value }}
                            </div>
                        </div>
                        <!-- 值 -->
                        <div v-else
                            class="text-text--primary text-[14px] font-[500] leading-[18px] overflow-ellipsis overflow-x-hidden">
                            {{ item.value }}
                        </div>
                    </slot>
                </div>
            </template>

            <!-- loading -->
            <template v-slot:loading>
                <mrc_ess_SkeletonLoader :loading="props.loading || loading"></mrc_ess_SkeletonLoader>
            </template>

        </v-data-table>

        <!-- 分页器 -->
        <mrc_ess_Paginations v-if="props.showPagination" :options="paginationOptions"
            :disabled="props.loading || loading">
        </mrc_ess_Paginations>

        <!-- 表格设置 -->
        <tableSettingsDialog ref="tableSettingsDialogRef" v-if="props.showSettings" :tableName="tableName"
            @confirm="handleTableSettingsConfirm"></tableSettingsDialog>
    </div>
</template>

<script lang="ts" setup>
import { ref, watch, onMounted, onUnmounted, toRaw, nextTick } from 'vue';
import { useCurrentInstance } from "@Hooks/index.ts";
const proxy = useCurrentInstance().proxy;

const emit = defineEmits(["view", "edit", "del", "add"]);
const props = defineProps({
    loading: {
        type: Boolean,
        default: false
    },
    items: {
        type: Array,
        default: []
    },





    // 表格的名字 ps:用于eventBus的事件调用，和表格参数缓存记录
    name: {
        type: String,
        default: ""
    },
    // 表格的键
    itemValue: {
        type: String,
        default: "id"
    },
    // 表格类型 1 普通 2 紧密
    tableType: {
        type: [String, Number],
        default: 1
    },
    // 表格的字段信息
    tableFields: {
        type: Array<any>,
        default: []
    },
    // 是否自动加载数据
    autoLoadData: {
        type: Boolean,
        default: true
    },
    // 请求数据的API地址
    dataApiUrl: {
        type: String,
        default: ""
    },
    // 删除数据的API地址
    delApiUrl: {
        type: String,
        default: ""
    },
    // 条件数据
    queryData: {
        type: Object,
        defautl: () => { }
    },
    // 排序的字段
    sortBy: {
        type: String,
        default: ""
    },
    // 排序的方式
    sortOrder: {
        type: String,
        default: ""
    },
    // 显示的操作 ["view", "edit", "del"]
    opt: {
        type: Array,
        default: () => ["view"]
    },
    // 是否显示添加按钮
    showAddBtn: {
        type: Boolean,
        default: false
    },
    // 是否显示分页
    showPagination: {
        type: Boolean,
        default: true
    },
    // 是否开启数据的拖拽排序
    dataDragSortable: {
        type: Boolean,
        default: false
    },
    // 是否可以设置表格
    showSettings: {
        type: Boolean,
        default: false
    },
    // 是否显示选择框
    showSelect: {
        type: Boolean,
        default: false
    },
    // 选中的数据返回类型
    returnObject: {
        type: Boolean,
        default: false
    }
})

// 表格名字
const tableName = props.name || proxy.$route.name;

// 表格类型
const tableType = ref(props.tableType);

// 表格字段
const tableFields = ref(initTable(toRaw(props.tableFields)));

// 请求数据的API地址
const dataApiUrl = ref(props.dataApiUrl);

// 删除数据的API地址
const delApiUrl = ref(props.delApiUrl);

// 查询的条件数据
const queryData = ref(props.queryData);

// 排序的字段
const sortBy = ref(props.sortBy);

// 排序的方式
const sortOrder = ref(props.sortOrder);

// 加载状态
const loading = ref(false);

const items = ref(props.items || []);

// 表头
const headers = ref<any>([]);

// 表格设置弹窗
const tableSettingsDialogRef = ref<any>(null);
// 打开表格设置
function handleShowSettings() {
    tableSettingsDialogRef.value.open({
        tableFields: toRaw(tableFields.value),
        tableType: toRaw(tableType.value)
    })
}
// 表格设置确认
function handleTableSettingsConfirm(data: any) {
    tableFields.value = data.tableFields;
    tableType.value = data.tableType;
}

// 初始化表格字段
function initTable(fields: Array<any>) {
    let list: Array<any> = [].concat(fields || []);
    for (let item of fields) {
        // 键
        item['key'] = (item.field || item.key);
        // 表头标题
        if (!item['title']) {
            item['title'] = "";
        }
        // 国际化表头字段
        if (!item['i18n']) {
            item['i18n'] = "";
        }
        // 是否显示数据拖拽排序按钮 -- 用于数据拖拽排序
        if (!item['dataDragSortBtn']) {
            item['dataDragSortBtn'] = false;
        }
        // 是否可以排序 -- 用于请求条件
        if (item['sortable'] === true) {
            item['sortable'] = true;
        } else {
            item['sortable'] = false;
        }
        // 是否可以排序 -- 用于表格设置
        if (item['key'] == "opt" || item['settingsSortable'] === false) {
            item['settingsSortable'] = false;
        } else {
            item['settingsSortable'] = true;
        }
        // 是否可以编辑隐藏/显示 -- 用于表格设置
        if (item['key'] == "opt" || item['editShow'] === false) {
            item['editShow'] = false;
        } else {
            item['editShow'] = true;
        }
        // 是否隐藏
        if (item['show'] == false) {
            item['show'] = false;
        } else {
            item['show'] = true;
        }
        // 表头插槽
        item['headerSlotKey'] = 'header.' + item['key'];
        // 内容插槽
        item['itemSlotKey'] = 'item.' + item['key'];
        // 样式
        let _class = [];
        if (item.align == "center") {
            _class.push("text-center");
        }
        item['class'] = _class.join(" ");
    }
    return list;
}

// 表格头部变化监听
watch(tableFields, () => {
    let _headers = [];
    for (let item of tableFields.value) {
        let obj: any = {};
        obj.key = item.key;
        // 宽度
        if (item.width) {
            if (item.key == "opt") {
                item.width = 64;
            }
            obj['width'] = Number(item.width) + 32;
            // 默认设置，以防宽度被压
            obj['minWidth'] = Number(item.width) + 32;
        }
        // 最小宽度
        if (item.minWidth) {
            obj['minWidth'] = item.minWidth;
        }
        // 最大宽度
        if (item.maxWidth) {
            obj['maxWidth'] = item.maxWidth;
        } else {
            // 默认设置，以防数据过长
            obj['maxWidth'] = 300;
        }
        // 是否换行
        if (item.nowrap) {
            obj['nowrap'] = item.nowrap;
        }
        // 是否开启筛选
        if (item.filter) {
            obj['filter'] = item.filter;
        }
        // if (item.fixed) {
        //     obj['fixed'] = item.fixed;
        // }
        // 对齐方式
        if (item.align) {
            obj['align'] = item.align;
        }
        // 是否显示
        if (item.show !== false) {
            _headers.push(obj);
        }
    }
    headers.value = _headers;
}, {
    immediate: true,
    deep: true
})

watch(() => props.items, () => {
    let dataArr = props.items || [];
    items.value = dataArr;
}, {
    immediate: true
})

// 页数列表
const pagesizeSelectList = [5, 10, 15, 20];

// 分页数据
const paginationOptions = ref({
    pagesize: props.showPagination == true ? (proxy.$ls.get("pagesize") || pagesizeSelectList[0]) : 999999999, //条数   不显示分页显示最大页数
    cpage: 1,  //当前页数
    totalcount: 1000, //总条数
    totalpage: 25, //总页数
    selectlist: pagesizeSelectList // 页数列表
})

/**
 * 排序字段变化
 */
function handleChangeSortBy(sort:string) {
    if (sortBy.value == sort) {
        if (sortOrder.value == "desc") {
            sortOrder.value = "asc";
        } else if (sortOrder.value == "asc") {
            sortBy.value = "";
            sortOrder.value = "";
        }
    } else {
        sortBy.value = sort;
        sortOrder.value = "desc";
    }
    refresh(1);
}
/**
 * 刷新
 */
function refresh(page: number | null = null) {
    if (page && typeof(page) == 'number') {
        if (page == paginationOptions.value.cpage) {
            loadData();
        } else {
            paginationOptions.value.cpage = page;
        }
    } else {
        loadData();
    }
}
/**
 * 加载数据
 */
function loadData() {
    // 加载中就不可以再次加载
    if (loading.value) {
        return;
    }
    loading.value = true;
    setTimeout(() => {
        loading.value = false;
    }, 500)
}

// 打开自动加载数据
if (props.autoLoadData) {
    loadData();
}

// 监听当前页码变化
watch(() => paginationOptions.value.cpage, () => {
    // 加载数据
    loadData();
})
// 监听当前页条数变化
watch(() => paginationOptions.value.pagesize, () => {
    // 加载数据
    loadData();
    // 缓存页条数
    proxy.$ls.set("pagesize", paginationOptions.value.pagesize);
})




// 当前选中的行
const selected = ref();




// eventBus 事件总线
let eventBusName = tableName;
onMounted(() => {
    proxy.$bus.off('table-' + eventBusName);
    proxy.$bus.on('table-' + eventBusName, ({ method, data }: any) => {
        // 刷新
        if (method == 'refresh') {
            refresh(data);
        }
    })
})
onUnmounted(() => {
    proxy.$bus.off('table-' + eventBusName);
})

/**
 * 点击查看
 * @param row 
 */
function handleView(row: any) {
    emit("view", {
        data: JSON.parse(JSON.stringify(toRaw(row.item))),
        row: row,
    });
}
/**
 * 点击编辑
 * @param row 
 */
function handleEdit(row: any) {
    emit("edit", {
        data: JSON.parse(JSON.stringify(toRaw(row.item))),
        row: row,
    });
}
/**
 * 点击删除
 * @param row 
 */
function handleDel(row: any, e: any) {
    e.showBtnLoading();
    setTimeout(() => {
        e.hideBtnLoading();
        e.close();
        refresh();
    }, 500);
    // emit("del", item);
}
/**
 * 点击添加
 */
function handleAdd() {
    emit("add");
}







// 拖拽排序
// Default SortableJS
import Sortable from 'sortablejs';
var dataDragSortableCreater: any = null;
function initDataDragSortable() {
    if (dataDragSortableCreater) {
        dataDragSortableCreater.destroy();
        dataDragSortableCreater = null;
    }
    nextTick(() => {
        var el = document.querySelector('.table-' + tableName + ' .v-table__wrapper tbody');
        dataDragSortableCreater = Sortable.create(el, {
            animation: 150,
            handle: '.sort-btn', // handle's class
            dataIdAttr: 'data-id',
            // 拖拽元素改变位置的时候
            onChange: function (evt) {
                // console.log(evt);
            }
        });
    })
}
// 监听开启拖拽排序
watch(() => props.dataDragSortable, (val) => {
    if (props.dataDragSortable == true) {
        initDataDragSortable();
    }
}, {
    immediate: true
})
// 销毁拖拽排序
onUnmounted(() => {
    if (dataDragSortableCreater) {
        dataDragSortableCreater.destroy();
        dataDragSortableCreater = null;
    }
})


defineExpose({
    refresh
})

</script>

<style scoped>
/* 上下间距 */
.my-data-table :deep(.v-data-table__td) {
    padding-top: 12px !important;
    padding-bottom: 12px !important;
}

/* 顶部栏样式 */
.my-data-table :deep(thead .v-data-table__td) {
    border-bottom: none !important;
}

.my-data-table :deep(thead tr th) {
    background-color: rgb(var(--v-theme-table-header-bg)) !important;
    box-shadow: none !important;
}

.my-data-table :deep(thead tr th:nth-child(1)) {
    border-radius: 8px 0 0 8px;
}

.my-data-table :deep(thead tr th:nth-last-child(1)) {
    border-radius: 0 8px 8px 0;
}

/* 分页隐藏 */
.my-data-table :deep(.v-data-table-footer) {
    display: none;
}

.my-data-table :deep(.v-divider) {
    display: none;
}

/* 表格滚动 */
.my-data-table.scroll_table_y {
    height: 100%;
    flex: 1;
}

.my-data-table.scroll_table_y :deep(.v-table__wrapper) {
    height: 100px;
}

.my-data-table.scroll_table_y :deep(.v-table__wrapper::-webkit-scrollbar) {
    display: inline-block !important;
    height: 5px !important;
    width: 5px !important;
}

/* 表格内容换行 */
.table-td-content> :deep(div) {
    overflow-x: inherit;
    text-overflow: inherit;
}

/* 表格loading时添加滚动条间距 */
.my-data-table.scroll_table_y.v-data-table--loading :deep(.v-table__wrapper) {
    /* padding-right: 5px; */
}
</style>